<?php
namespace App\Models\Traits;

use Carbon\Carbon;
use App\Services\BoughtVip\BoughtVip;

trait HasUserVipPurchase
{
	public function plusVipPeriod()
	{
		$vipPeriod = (int)cs('sale')->vip_period;
		
		$vipExpiredAt = $this->vip_expired_at
			? $this->vip_expired_at->addDays($vipPeriod)
			: Carbon::now()->addDays($vipPeriod);
		
		$this->vip_expired_at = $vipExpiredAt;
		$this->save();
	}
	
	public function minusVipPeriod()
	{
		$vipPeriod = ((int)cs('sale')->vip_period) * -1;
		
		$vipExpiredAt = $this->vip_expired_at ? $this->vip_expired_at->addDays($vipPeriod) : null;
		
		$this->vip_expired_at = $vipExpiredAt;
		$this->save();
	}
	
	public function boughtVipRecords()
	{
		return $this->vipPurchases()->whereNotNull('paid_at')->whereNull('cancelled_at')->orderBy('id')->get();
	}
	
	public function boughtVipCount()
	{
		return $this->vipPurchases()->whereNotNull('paid_at')->whereNull('cancelled_at')->count();
	}
	
	public function firstBoughtVipRecord()
	{
		return $this->vipPurchases()->whereNotNull('paid_at')->whereNull('cancelled_at')->orderBy('id')->first();
	}
	
	public function lastBoughtVipRecord()
	{
		return $this->vipPurchases()->whereNotNull('paid_at')->whereNull('cancelled_at')->orderByDesc('id')->first();
	}
	
	public function vipExpiryAfterBuying()
	{
		$vipPeriod = (int)cs('sale')->vip_period;
		
		if (! $this->vip_expired_at) {
			return Carbon::now()->addDays($vipPeriod);
		}

		if (Carbon::parse($this->vip_expired_at)->gte(Carbon::today())) {
			return Carbon::parse($this->vip_expired_at)->addDays($vipPeriod);
		} else {
			return Carbon::now()->addDays($vipPeriod);
		}
	}
	
	public function vipExpiryFromPurchase()
	{
		if ($this->hasNotBoughtVip()) return null;
		
		$vipExpiredAt = null;
		$vipPeriod = (int)cs('sale')->vip_period;
		
		$purchases = $this->boughtVipRecords();
		
		if ($purchases->count() <= 0) return null;
		
		foreach ($purchases as $purchase) {
			if (! $vipExpiredAt) {
				$vipExpiredAt = $purchase->paid_at->addDays($vipPeriod);
			} else {
				if ($vipExpiredAt->gte($purchase->paid_at)) {
					$vipExpiredAt = $vipExpiredAt->addDays($vipPeriod);
				}
				if ($vipExpiredAt->lt($purchase->paid_at)) {
					$vipExpiredAt = $purchase->paid_at->addDays($vipPeriod);
				}
			}
		}
		return $vipExpiredAt;
	}
	
	public function hasBoughtVip()
	{
		return $this->boughtVipCount() > 0;
	}
	
	public function hasNotBoughtVip()
	{
		return !$this->hasBoughtVip();
	}
	
	public function isFirstBuyingVip()
	{
		return $this->boughtVipCount() < 1;
	}
	
	public function isFirstBoughtVip()
	{
		return $this->boughtVipCount() === 1;
	}
	
	public function isRechargingVip()
	{
		return $this->isVip() and $this->isFirstBoughtVip();
	}
	
	public function isRechargedVip()
	{
		return $this->isVip() and $this->boughtVipCount() > 1;
	}
	
	public function giftVip()
	{
		return app(BuyingVip::class)->gift($this);
	}
	
	public function buyVip()
	{
		return app(BuyingVip::class)->buy($this);
	}
	
	public function salerVip()
	{
		return app(BuyingVip::class)->saler($this);
	}
	
	public function boughtVip()
	{
		return app(BoughtVip::class, [
			'user' => $this
		])->make();
	}
	
	public function isVipBuyingLimited()
	{
		$lastDayVipsCount = counter('user')->buyVipsCount(Carbon::yesterday());
		$todayVipsCount = counter('user')->buyVipsCount(Carbon::today());
		
		$vipLimitStartNumber = (int)cs('sale')->vip_limit_start_number;
		$vipLimitExceedPercent = (int)cs('sale')->vip_limit_exceed_last_day_percent;
		
		if ($vipLimitExceedPercent <= 0) return false;
		
		if ($todayVipsCount == 0) return false;
		
		if ($todayVipsCount < $vipLimitStartNumber) return false;
		
		$limitedCount = $lastDayVipsCount + $lastDayVipsCount * $vipLimitExceedPercent * 0.01;
		
		if ($todayVipsCount > $limitedCount) {
			return true;
		}
		return false;
	}
}
